home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Text⁄Files / think c pap ƒ / think-c-pap-routines-c.txt^M next >
Encoding:
Text File  |  1989-02-05  |  9.8 KB  |  395 lines  |  [TEXT/MACA]

  1. cat think-c-pap-routines-c.txt
  2. /* Routines to interface to PAP driver. See MacTutor, Sep '86; also Jan '88.
  3.    This routines are meant to replace the assembly language "glue"
  4.    given in the Sep '86 article. Refer to the article for info on how to
  5.    use these routines.
  6.    
  7.    Sak Wathanasin (sw%kernel.co.uk or ....!mcvax!ukc!kernel!sw)
  8.  
  9.    This file (or a project built from it) can be included in any project
  10.    that wants to talk to the PAP routines, but you must provide two external
  11.    routines, PrintErr and Fatal (they take a Str255 and a short err number).
  12.    
  13. Synopsis:
  14.    
  15.    typedef struct
  16.         { long  systemStuff;
  17.           char  statusStr[256];
  18.         } papStatusRec, *papStatusPtr;
  19.         
  20.    pascal short PAPOpen (refNum, printerName, flowQuantum, statusBuf, compState)
  21.     short           *refNum;
  22.     char            *printerName;
  23.     short           flowQuantum;
  24.     papStatusPtr    statusBuf;
  25.     
  26.    pascal short PAPRead (refNum, buffer, length, eof, compState);
  27.     short           refNum;
  28.     char            *buffer;
  29.     short           *length;
  30.     short           *eol;
  31.     short           *compState;
  32.  
  33.    pascal short PAPWrite (refNum, buffer, length, eof, compState)
  34.     short           refNum;
  35.     char            *buffer;
  36.     short           length;
  37.     short           eol;
  38.     short           *compState;
  39.     
  40.    pascal short PAPClose (refNum);
  41.     short           refNum;
  42.    
  43.     typedef struct AddrBlock {
  44.         short           aNet;
  45.         Byte            aNode;
  46.         Byte            aSocket;
  47.     } AddrBlock;
  48.             
  49.    pascal short PAPStatus (printerName, statusBuff, netAddr)
  50.     char            *printerName;
  51.     papStatusPtr    statusBuff;
  52.     AddrBlock       *netAddr;
  53.     
  54.    short PAPLoad ();
  55.    short PAPUnload();
  56. */
  57.  
  58. #include    "pap.h"
  59. #define     NIL 0L
  60.  
  61. Handle  pap=NIL;            /* these static vars don't have to be locked */
  62. Ptr     papPtr;             /* points to locked PAP mgr */
  63. Handle  lwNameH;            /* handle to locked entity name */
  64. StringPtr
  65.         lwNameP,            /* ptr to same */
  66.         lwTypeP,
  67.         lwZoneP;
  68.  
  69. #ifdef  TEST
  70. /* test routines divert output to a file, so I can test
  71.    without an LW present */
  72.         
  73. short   psRef=-1;
  74. struct  {
  75.     short   *comp,
  76.             len,
  77.             eof;
  78.     Boolean inUse;
  79.     long    delay;
  80. }   wInfo=  {NIL, 0, 0, FALSE, 0L};
  81.  
  82. struct  {
  83.     short   *comp,
  84.             *len,
  85.             *eof;
  86.     char    *buff;
  87.     Boolean inUse;
  88.     long    delay;
  89. }   rInfo=  {NIL, NIL, NIL, NIL, FALSE, 0L};
  90.  
  91. pascal short PAPOpen (refNum, printerName, flowQuantum, statusBuf, compState)
  92. short           *refNum;
  93. char            *printerName;
  94. short           flowQuantum;
  95. papStatusPtr    statusBuf;
  96. short           *compState;
  97. {
  98. #   define  zeroLoc 10
  99.     static  Str255  fName="\pPS Dump 00";
  100.  
  101.     (void)Create(fName, 0, 'PEDT', 'TEXT');
  102.     (void)FSOpen(fName, 0, &psRef);
  103.     if (++fName[zeroLoc] > '9') {
  104.         fName[zeroLoc] = '0';
  105.         fName[zeroLoc-1]++;
  106.     }
  107.     
  108.     *refNum = 0;
  109.     wInfo.comp = compState;
  110.     *compState = 1;
  111.     wInfo.delay = TickCount() + ( Random() % DELAY_FACTOR);
  112.     wInfo.inUse = TRUE;
  113.     return ((short)noErr);
  114. }
  115.  
  116.     
  117. pascal short PAPRead (refNum, buffer, length, eof, compState)
  118.     short           refNum;
  119.     char            *buffer;
  120.     short           *length;
  121.     short           *eof;
  122.     short           *compState;
  123. {
  124.     long    tdelay;
  125.     rInfo.comp = compState;
  126.     *compState = 1;
  127.     rInfo.eof = eof;
  128.     rInfo.len = length;
  129.     rInfo.buff = buffer;
  130.     tdelay = ( Random() % DELAY_FACTOR);
  131.     rInfo.delay = TickCount() + tdelay;
  132.     rInfo.inUse = TRUE;
  133.     return((short)noErr);
  134. }
  135.  
  136. pascal short PAPWrite (refNum, buffer, length, eof, compState)
  137.     short           refNum;
  138.     char            *buffer;
  139.     short           length;
  140.     short           eof;
  141.     short           *compState;
  142. {
  143.     long            psCnt;
  144.     OSErr           err=noErr;
  145.     long            tdelay;
  146.     
  147.     wInfo.comp = compState;
  148.     *compState = 1;
  149.     wInfo.eof = eof;
  150.     wInfo.len = length;
  151.     tdelay = ( Random() % DELAY_FACTOR);
  152.     wInfo.delay = TickCount() + tdelay;
  153.     if (wInfo.inUse) return (-4101);
  154.     else {
  155.         wInfo.inUse = TRUE;
  156.         psCnt = (long)length;
  157.         err = FSWrite (psRef, &psCnt, buffer);
  158.         return((short)err);
  159.     }
  160. }
  161.     
  162. pascal short PAPClose (refNum)
  163.     short           refNum;
  164.    
  165. {
  166.     long    psTotal;
  167.     
  168.     wInfo.comp = NIL;
  169.     wInfo.eof = 0;
  170.     wInfo.len = 0;
  171.     wInfo.inUse = FALSE;
  172.     wInfo.delay = 0L;
  173.     rInfo.comp = NIL;
  174.     rInfo.eof = NIL;
  175.     rInfo.len = NIL;
  176.     rInfo.buff = NIL;
  177.     rInfo.inUse = FALSE;
  178.     rInfo.delay = 0L;
  179.     if (psRef >= 0) {
  180.         (void) GetFPos (psRef, &psTotal);
  181.         (void) SetEOF (psRef, psTotal);
  182.         (void)FSClose(psRef);
  183.         (void)FlushVol(nil, 0);
  184.     }
  185.     psRef = -1;
  186.     return(0);
  187. }
  188.  
  189. pascal short PAPStatus (printerName, statusBuff, netAddr)
  190.     char            *printerName;
  191.     papStatusPtr    statusBuff;
  192.     AddrBlock       *netAddr;
  193. {
  194.     static  Str255  writing="\p status: writing",
  195.                     idle="\p status: idle",
  196.                     talking="\p status: talking";
  197.     
  198.     if (wInfo.inUse)
  199.         BlockMove(writing, statusBuff->statusStr, (Size)sizeof(writing));
  200.     else if (rInfo.inUse)
  201.         BlockMove(talking, statusBuff->statusStr, (Size)sizeof(talking));
  202.     else
  203.         BlockMove(idle, statusBuff->statusStr, (Size)sizeof(idle));
  204.     return(0);
  205. }
  206.  
  207. extern long     randSeed;
  208. short PAPLoad ()
  209. {
  210.     static  Str255  lw="\pFake LaserWriter",
  211.                     lwt="\pLaserWriter",
  212.                     lwz="*";
  213.     lwNameP = lw;
  214.     lwTypeP = lwt;
  215.     lwZoneP = lwz;
  216.     GetDateTime(&randSeed);
  217.     return(0);
  218. }
  219.                 
  220. short PAPUnload()
  221. {
  222.     return(0);
  223. }
  224.  
  225. FakeRead()
  226. {
  227.     static char rubbish[]="Just some rubbish\n";
  228.     
  229.     if (wInfo.eof) {
  230.         *(rInfo.eof) = 1;
  231.         *(rInfo.len) = 0;
  232.         wInfo.eof = 0;
  233.     }
  234.     else {
  235.         *(rInfo.eof) = 0;
  236.         *(rInfo.len) = sizeof(rubbish)-1;
  237.         BlockMove(rubbish, rInfo.buff, (Size)sizeof(rubbish)-1);
  238.     }
  239.     *(rInfo.comp) = 0;
  240.     rInfo.comp = NIL;
  241.     rInfo.eof = NIL;
  242.     rInfo.len = NIL;
  243.     rInfo.buff = NIL;
  244.     rInfo.inUse = FALSE;
  245.     rInfo.delay = 0L;
  246. }
  247.  
  248. FakeWrite()
  249. {
  250.     *(wInfo.comp) = 0;
  251.     wInfo.comp = NIL;
  252.     wInfo.len = 0;
  253.     wInfo.inUse = FALSE;
  254.     wInfo.delay = 0L;
  255. }
  256.  
  257. void TestDelay()
  258. {
  259.     long    myTick;
  260.     
  261.     myTick = TickCount();
  262.     if (rInfo.inUse && myTick > rInfo.delay) FakeRead();
  263.     if (wInfo.inUse && myTick > wInfo.delay) FakeWrite();
  264. }
  265.  
  266. #else   TEST
  267. short PAPLoad ()
  268. {   short   res;
  269.     OSErr   err;
  270.     char    NullString='\0';
  271.     Str255  DVolname;
  272.     short   DVolRefnum;
  273.     SysEnvRec
  274.             theWorld;
  275.     
  276.     /* we need to find the LaserWriter file on the boot volume
  277.        or 'blessed' folder without making a permanent change
  278.        in the current default volume; under HFS the "poor man's
  279.        search path" is used by default */
  280.     
  281.     (void) SysEnvirons(1, &theWorld);
  282.     (void) GetVol (&DVolname, &DVolRefnum);
  283.     (void) SetVol( &NullString, theWorld.sysVRefNum);
  284.  
  285.     res = OpenResFile ("\pLaserWriter");    /* we should get this name from
  286.                                                the Chooser (in STR -8192) */
  287.     if ( res < 0 ) {
  288.         /* couldn't find the file */
  289.         Fatal("\pCan't find LaserWriter file", res);
  290.         return (res);
  291.     }
  292.  
  293.     /* Read the PAP code into memory & lock it down */
  294.     if ((pap = GetResource('PDEF', 10)) == NIL || (err = ResError()) ) {
  295.         /* oops! something wrong */
  296.         Fatal("\pCouldn't load PAP resources:", err);
  297.         if (res != -1) /* the file was opened earlier */
  298.             CloseResFile (res);
  299.         return (err);
  300.     };
  301.  
  302.     MoveHHi(pap);           /* relocate to top of application heap */
  303.     HLock(pap);             /* lock it */
  304.     DetachResource(pap);    /* and detach from the file's resource map */
  305.     papPtr = *pap;
  306.                             /* save the addr in a global; it's OK to do
  307.                                this as we've locked it */
  308.     
  309.     /* Now get the printer entity name from the LaserWriter file */
  310.  
  311.     if ((lwNameH = GetResource('PAPA', -8192)) == NIL || (err = ResError()) ) {
  312.         Fatal("Couldn't get LaserWriter name: ", err);
  313.         return(err);
  314.     }
  315.  
  316.     /* Move to top of heap & lock the name */
  317.     MoveHHi(lwNameH);
  318.     HLock(lwNameH);
  319.     DetachResource(lwNameH);
  320.     lwNameP = (StringPtr)(*lwNameH);
  321.     lwTypeP = lwNameP + (short)lwNameP[0] + 1;
  322.     lwZoneP = lwTypeP + (short)lwTypeP[0] + 1;
  323.  
  324.     /* We're done with the LaserWriter file */
  325.     CloseResFile(res);
  326.     (void) SetVol (&NullString, DVolRefnum);
  327.     return(0);
  328. }
  329.  
  330. pascal short PAPOpen ()
  331. /* no params to stop LSC generating a stack frame */
  332. {
  333.     asm{
  334.         move.l  papPtr, A0
  335.         jmp     0(A0)
  336.     }
  337. }
  338.  
  339. pascal short PAPRead ()
  340. /* no params to stop LSC generating a stack frame */
  341. {
  342.     asm{
  343.         move.l  papPtr, A0
  344.         jmp     4(A0)
  345.     }
  346. }
  347.  
  348. pascal short PAPWrite ()
  349. /* no params to stop LSC generating a stack frame */
  350. {
  351.     asm{
  352.         move.l  papPtr, A0
  353.         jmp     8(A0)
  354.     }
  355. }
  356.  
  357. pascal short PAPStatus ()
  358. /* no params to stop LSC generating a stack frame */
  359. {
  360.     asm{
  361.         move.l  papPtr, A0
  362.         jmp     12(A0)
  363.     }
  364. }
  365.  
  366. pascal short PAPClose ()
  367. /* no params to stop LSC generating a stack frame */
  368. {
  369.     asm{
  370.         move.l  papPtr, A0
  371.         jmp     16(A0)
  372.     }
  373. }
  374.  
  375. /* The PAP driver installs several VBL tasks that must be removed
  376.    using the PAP unload call before disposing of the PAP code
  377. */
  378. short PAPUnload()
  379. {   short   res;
  380.     asm{
  381.         subq.l  #2, sp
  382.         move.l  papPtr, A0
  383.         jsr     20(A0)
  384.         move.w  (sp)+, res      /* save the result from the PAP call */
  385.     }
  386.     /* can PAPUnload ever return an error? We assume not... */
  387.  
  388.     HUnlock(lwNameH);
  389.     DisposHandle(lwNameH);      /* junk the LW name */
  390.     HUnlock(pap);
  391.     DisposHandle(pap);
  392.     return(res);
  393. }
  394. #endif  TEST
  395. command: